#include "InfoWidget.hpp"
#include "TextItemDelegate.hpp"
#include "../cl/PlatformInfo.hpp"
#include "../cl/DeviceInfo.hpp"
#include <Qt>
#include <QVBoxLayout>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QHeaderView>
#include <QApplication>
#include <QClipboard>
#include <QKeyEvent>

using namespace ui;

namespace {
    const char * const PROPERTIES[] = {
        QT_TR_NOOP("Platform Name:"),     QT_TR_NOOP("Vendor:"),
        QT_TR_NOOP("Version:"),           QT_TR_NOOP("Profile:"),
        QT_TR_NOOP("Extensions"),         QT_TR_NOOP("Device Name:"),
        QT_TR_NOOP("Hardware Version:"),  QT_TR_NOOP("Software Version:"),
        QT_TR_NOOP("OpenCL C Version:"),  QT_TR_NOOP("Compute Units:"),
        QT_TR_NOOP("Cache Size:"),        QT_TR_NOOP("Base Clock Freq.:"),
        QT_TR_NOOP("Memory Size:"),       QT_TR_NOOP("Extensions:"),
        QT_TR_NOOP("Max. Items/Dimen.:"), QT_TR_NOOP("Max. Items/Group:")
    };
    const int ROWS = sizeof(PROPERTIES) / sizeof(char *);
    const int COLUMNS = 2;
}

InfoWidget::InfoWidget(
        const cl::Platform &platform, const cl::Device &device,
        QWidget *parent) :
    QWidget(parent),
    tableWidget(new QTableWidget(ROWS, COLUMNS)),
    clipboardData(new QString()) {
    QVBoxLayout *layout = new QVBoxLayout();
    setLayout(layout);
    layout->addWidget(tableWidget);
    cl::PlatformInfo platformInfo = cl::PlatformInfo(platform);
    cl::DeviceInfo deviceInfo = cl::DeviceInfo(device);
    tableWidget->setShowGrid(false);
    tableWidget->horizontalHeader()->hide();
    tableWidget->horizontalHeader()->setStretchLastSection(true);
    tableWidget->verticalHeader()->hide();
    tableWidget->setItemDelegate(new TextItemDelegate(tableWidget));
    for(int i=0; i<ROWS; i++)
        tableWidget->setItem(i, 0, new QTableWidgetItem(tr(PROPERTIES[i])));
    tableWidget->setItem(0, 1, new QTableWidgetItem(platformInfo.getName()));
    tableWidget->setItem(1, 1, new QTableWidgetItem(platformInfo.getVendor()));
    tableWidget->setItem(2, 1, new QTableWidgetItem(platformInfo.getVersion()));
    tableWidget->setItem(3, 1, new QTableWidgetItem(platformInfo.getProfile()));
    tableWidget->setItem(4, 1, new QTableWidgetItem(platformInfo.getExtensions()));
    tableWidget->setItem(5, 1, new QTableWidgetItem(deviceInfo.getName()));
    tableWidget->setItem(6, 1, new QTableWidgetItem(deviceInfo.getHardwareVersion()));
    tableWidget->setItem(7, 1, new QTableWidgetItem(deviceInfo.getSoftwareVersion()));
    tableWidget->setItem(8, 1, new QTableWidgetItem(deviceInfo.getOpenCLCVersion()));
    tableWidget->setItem(9, 1, new QTableWidgetItem(deviceInfo.getComputeUnits()));
    tableWidget->setItem(10, 1, new QTableWidgetItem(deviceInfo.getCacheSize()));
    tableWidget->setItem(11, 1, new QTableWidgetItem(deviceInfo.getBaseClockFrequency()));
    tableWidget->setItem(12, 1, new QTableWidgetItem(deviceInfo.getMemorySize()));
    tableWidget->setItem(13, 1, new QTableWidgetItem(deviceInfo.getExtensions()));
    tableWidget->setItem(14, 1, new QTableWidgetItem(deviceInfo.getMaxWorkItemsPerWorkGroup()));
    tableWidget->setItem(15, 1, new QTableWidgetItem(deviceInfo.getMaxWorkGroupSize()));
    tableWidget->resizeColumnsToContents();
    tableWidget->resizeRowsToContents();
    setFocusPolicy(Qt::StrongFocus);
    connect(tableWidget, SIGNAL(itemSelectionChanged()),
            this, SLOT(onItemSelectionChanged()));
}

InfoWidget::~InfoWidget(void) {
    if(clipboardData) {
        delete clipboardData;
        clipboardData = 0;
    }
}

void InfoWidget::onItemSelectionChanged(void) {
    QList<QTableWidgetItem *> selections(tableWidget->selectedItems());
    clipboardData->clear();
    for(int i=0, j=selections[i]->row(); i<selections.size(); i++) {
        const QTableWidgetItem *item = selections[i];
        if(item->row() != j) { clipboardData->append("\r\n"); j = item->row(); }
        if(item->column() % COLUMNS) { clipboardData->append("\t"); }
        clipboardData->append(item->text());
    }
    clipboardData->append("\r\n");
}

void InfoWidget::keyPressEvent(QKeyEvent *event) {
    if(event->key() == Qt::Key_C && event->modifiers() & Qt::ControlModifier) {
        QApplication::clipboard()->setText(*clipboardData);
    }
}
